package com.jdd.fintech.morse.plugin.strategy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jdd.fintech.morse.plugin.ecrypts.SymmetricCrypto;
import com.jdd.fintech.morse.plugin.enums.BizErrorCodeEnum;
import com.jdd.fintech.morse.plugin.enums.ReturnCodeEnum;
import com.jdd.fintech.morse.plugin.plugconfig.MorsePlugValueConfig;
import com.jdd.fintech.morse.plugin.strategy.context.AbstractDataEncryptAndDecryptStrategy;
import com.jdd.fintech.morse.plugin.util.CryptoUtils;
import com.jddglobal.filter.support.exception.FilterException;
import com.jddglobal.phevos.gateway.resources.ResourceCapability;
import org.apache.commons.lang3.StringUtils;

/**
 * @description: 标准化数据加密策略类
 * @credit: 2021-12-24 11:05
 * @author: fengcheng
 **/
public class MsDataEncryptAndDecryptStrategy extends AbstractDataEncryptAndDecryptStrategy {

    /**
     * 数据加密策略接口方法(标准化使用)
     * @param plugValueConfig   插件值对象
     * @param jsonObject        请求对象
     * @param scObj             算法对象
     * @return
     * @throws FilterException
     */
    @Override
    public String dataEncryptsStrategyMethod(MorsePlugValueConfig plugValueConfig, JSONObject jsonObject, SymmetricCrypto scObj) throws FilterException {
        //是否完整加解密
        String ciphertext = null;
        String plaintext = null;
        try {
            //星链接口返回 code，标准化返回 resCode
            //前后端匹配
            if (ReturnCodeEnum.SUCCESS.getCode().equals(jsonObject.getString("resCode")) || ReturnCodeEnum.SCSUCCESS.getCode().equals(jsonObject.getString("code"))) {
                jsonObject.put("code", ReturnCodeEnum.SUCCESS.getDesc());
            } else {
                if (jsonObject.getString("resCode") != null) {
                    jsonObject.put("code",  jsonObject.getString("resCode"));
                }
            }
            //星链接口返回 data，标准化返回 resData
            if (jsonObject.getString("resData") != null) {
                jsonObject.put("data", jsonObject.get("resData"));
            }

            //星链接口返回 desc，标准化返回 resMsg
            if (jsonObject.getString("resMsg") != null) {
                jsonObject.put("msg", jsonObject.getString("resMsg"));
            } else {
                jsonObject.put("msg", jsonObject.getString("desc"));
            }

            jsonObject.remove("desc");
            jsonObject.remove("resMsg");
            jsonObject.remove("resCode");
            jsonObject.remove("resData");
            //整个request请求对象
            plaintext = jsonObject.toJSONString();
            //加签
            String signature;
            signature = CryptoUtils.signMS(plaintext);
            jsonObject.put("signature", signature);

            //完整加密并放到data中
            ciphertext = scObj.encryptBase64(plaintext).replace("\n", "");
            jsonObject.put("data", ciphertext);
        } catch (Exception e) {
            log.error("MsDataEncryptAndDecryptStrategy.dataEncryptsStrategyMethod.标准化|加密异常|明文字符串：{} 异常信息：{}", plaintext, e.getMessage(), e);
            throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_3.getCode(), BizErrorCodeEnum.FAILURE_3.getDesc()));
        }
        return jsonObject.toJSONString();
    }

    /**
     * 数据解密策略接口方法(标准化使用)
     * @param plugValueConfig   插件值对象
     * @param jsonObject        请求对象
     * @param scObj             算法对象
     * @return
     * @throws FilterException 方法
     */
    @Override
    public String dataDecryptsStrategyMethod(MorsePlugValueConfig plugValueConfig, JSONObject jsonObject, SymmetricCrypto scObj) throws FilterException {
        String ciphertext = jsonObject.getString("data");
        String sysSign = jsonObject.getString("signature");
        String salt = plugValueConfig.getSalt();
        // 如果responseData为null 不需要进行解密和验签
        try {
            if (StringUtils.isNotBlank(ciphertext)) {
                //开始进行解密操作
                String plaintext = scObj.decryptBase64(ciphertext);
                jsonObject.put("data", plaintext);
                boolean isVerifyPass = CryptoUtils.verifySignMS(salt, jsonObject, sysSign, plaintext);
                if (!isVerifyPass) {
                    log.error("MsDataEncryptAndDecryptStrategy.dataDecryptsStrategyMethod.标准化|解密验签|验签不通过|Salt:{}, sign:{}, 密文:{}", salt, sysSign, ciphertext);
                    throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_5.getCode(), BizErrorCodeEnum.FAILURE_5.getDesc()));
                }
            }
        } catch (Exception e) {
            log.error("decryptionOperation|morse请求参数解密|解密异常|密文字符串：{} 异常信息：{}", ciphertext, e.getMessage(), e);
            throw new FilterException(new ResourceCapability.AutoDefineResource(BizErrorCodeEnum.FAILURE_4.getCode(), BizErrorCodeEnum.FAILURE_4.getDesc()));
        }
        return "true";
    }

    /**
     * 构建公共请求对象(标准化使用)
     * @param plugValueConfig
     * @param tenantId
     * @param productCode
     * @param jsonObject
     * @return
     */
    @Override
    public String buildCommonRequestObjMethod(MorsePlugValueConfig plugValueConfig, String tenantId, String productCode, JSONObject jsonObject) {
        String requestData = jsonObject.getString("data");
        JSONObject jsonRequestData = JSON.parseObject(requestData, JSONObject.class);
        jsonRequestData.put("userId", jsonObject.getString("userId"));
        jsonRequestData.put("source", jsonObject.getString("source"));
        jsonRequestData.put("tenantId", jsonObject.getString("tenantId"));
        return jsonRequestData.toJSONString();
    }
}
